package interfacesFerrovia;

import java.util.Map;
import java.util.Set;

/**
 * Interface para acesso aos comandos da rede ferroviaria.
 * @author Fernando Vanini
 *
 */

public interface ControleFerrovia extends DefsGlobais{
	
	/**
	 * Registra um tratador para os eventos gerados pela rede ferroviaria.
	 * Pode-se registrar mais de um tratador
	 * @param tratador Objeto que implementa a interface TratadorDeEventos.
	 * @return true se o registro for feito normalmente.
	 */
	public boolean registraTratadorDeEventos(TratadorDeEventos tratador);
	
	/**
	 * Consulta aos elementos da rede. Retorna uma lista contendo os id's dos
	 * elementos da rede.
	 * @return lista contendo os id's dos elementos da rede.
	 */
	public String[] consultaElementos();
	
	/**
	 * Consulta os atributos fixos de um elemento da rede.
	 * @param idElemento identificacao unica do elemento.
	 * @return mapa <atributo,valor> contendo os atributos fixos do elemento.
	 */
	public Map<TipoAtributo,Object> consultaAtributosFixos(String idElemento);
	
	/**
	 * Consulta o estado (formado pelo conjunto de atributos variaveis) de
	 * um elemento da rede.
	 * @param idElemento identificacao unica do elemento.
	 * @return mapa <atributo,valor> que caracteriza o estado do elemento.
	 */
	public Map<TipoAtributo,Object> consultaEstado(String idElemento);
	
	/**
	 * Consulta um atributo de um elemento da rede.
	 * @param idElemento Identificacao unica do elemento
	 * @param atributo   Nome do atributo a ser consultado
	 * @return Object    Valor do atributo
	 */
	public Object consultaAtributo(String idElemento, TipoAtributo atributo);
	
	/**
	 * Consulta o conjunto de atributos de um dado elemento da rede.
	 * @param idElemento Identificacao unica do elemento da rede.
	 * @return Conjunto de atributos (fixos e variaveis) associados ao elemento.
	 */
	public Set<TipoAtributo> consultaListaDeAtributos(String idElemento);
	
	/**
	 * Comando para acelerar uma composicao.
	 * @param idComposicao Identificacao unica da composicao.
	 * @param velocidade   Velocidade a ser atingida.
	 * @param urgente      Urgente(true) ou normal(false).
	 * @return             Tempo necessario para atingir a velocidade.
	 */
	public int acelerarComposicao(String idComposicao, float velocidade, boolean urgente);
	
	/**
	 * Comando para frear a composicao.
	 * @param idComposicao Identificacao unica da composicao.
	 * @param velocidade   Velocidade a ser atingida
	 * @param urgente      Urgente(true) ou normal(false).
	 * @return             Tempo necessario para realizar a operacao.
	 */
	public int frearComposicao(String idComposicao, float velocidade, boolean urgente);
	
	/**
	 * COnsulta a posicao prevista para um instante futuro.
	 * @param idComposicao Identificacao unica da composicao.
	 * @param instante Instante futuro a ser considerado.
	 * @return A posicao prevista, no trecho atual.
	 */
	public float consultaPosicao(String idComposicao, int instante);
	
	/**
	 * Consulta o tempo previsto para atingir uma dada posicao no trecho atual
	 * (considerando a velocidade e taxa de aceleracao ou frenagem atuais).
	 * @param idComposicao Identificacao unica da composicao.
	 * @param posicao Posicao a ser atingida.
	 * @return Tempo estimado necessario para atingir a posicao.
	 */
	public int consultaTempo(String idComposicao, float posicao);
	
	/**
	 * Calcula a distancia minima necessaria e parada de uma composicao.
	 * @param idComposicao Identificacao unica da composicao.
	 * @return Distancia minima necessaria a parada da composicao.
	 */
	public float consultaDistMinParada(String idComposicao);

	
	/**
	 * Comando para mudar o estado de uma chave.
	 * @param idChave    Identificacao unica da chave
	 * @param idTrechoA  Identificacao do trecho a ser conectado a extremidade A da chave.
	 * @param idTrechoB  Identificacao do trecho a ser conectado a extremidade B da chave.
	 * @return           True se a operacao pode ser realizada.
	 */
	public boolean mudarChave(String idChave, String idTrechoA, String idTrechoB);
	
	/**
	 * Define a resolucao do relogio do simulador (intervalo entre tics).
	 * (default: 15s, habilitado = false)
	 * @param intervalo  Intervalo entre cada tic
	 * @param habilitado Indica se o simulador gera ou nao o evento relativo ao tic.
	 */
	//public void defineTic(int intervalo, boolean habilitado);	 eliminado => sera sempre 1 !!!!

	/**
	 * Define o cenario a ser usado na simulcao.
	 * @param cenario Indica o cenario a ser usado (0..nCenarios-1)
	 */	
	public void defineCenario(int cenario);
	
	/**
	 *    Simula um cenario pre-definido, formado por um conjunto de elementos de rede.
	 *    @param t1 Instante de inicio da simulacao (quase sempre zero).
	 *    @param t2 Instante de termino da simulacao.
	 * @throws Exception 
	 */
	public void simularCenario(int t1, int t2) throws Exception;

}
